package org.andes.kownledge.operator.func;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.andes.base.Bindings;
import org.andes.kownledge.operator.Key;
import org.andes.kownledge.operator.NoAtom;
import org.andes.kownledge.operator.Term;
import org.andes.kownledge.operator.Variable;

public abstract class Func extends NoAtom{
	

	public Func(){
		name=this.getClass().getSimpleName();
	}
	public String getFuncName(){
		return name;
	}
	public abstract Object doFunc();
	protected List<Term> vars=new ArrayList<Term>();

	protected Map<String,Term> keys=new HashMap<String,Term>();
	public List<Term> getVar() {
		return vars;
	}
	public void addVar(Term term){		
			vars.add(term);
	}
	public void addKey(Key key){
		keys.put(key.getType(), key.getValue());
	}
	public Func substBindings(Bindings bindings){
		Func result;
		try {
			result = this.getClass().newInstance();
			for(Term term:vars){
				Term term1=term.substBindings(bindings);
				result.addVar(term1);
			}
			return result;
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
		
	}
	public Func renameVariable(){
		Func result;
		try {
			result = this.getClass().newInstance();
			for(Term term:vars){
				Term term1=term.renameVariable();
				result.addVar(term1);
			}
			return result;
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
		
	}

//	public void setVars(List<Term> var) {
//		this.vars = var;
//	}
	public String toString(){
		StringBuffer resultb=new StringBuffer();
		resultb.append(this.getClass().getSimpleName());
		resultb.append("(");
		for(Term term:vars){
			resultb.append(term.toString());
			resultb.append("+");
			
		}
		resultb.append(")");
		return resultb.toString();
	}
	public boolean isGround(){
		for(Term var:vars){
			if(var instanceof Variable)
				return false;						
		}
		return true;
	}
	@Override
	public List<Variable> getVars() {
		List<Variable> result=new ArrayList<Variable>();
		for(Term term:vars){
			if(term instanceof NoAtom){
				result.addAll(((NoAtom)term).getVars());
			}else if(term instanceof Variable)
				result.add((Variable) term);
				
		}
		return result;
	}

}
